import java.util.PriorityQueue;
import java.util.Comparator;

class MyTimerTask implements Comparable<MyTimerTask>{
   private Runnable task;
  private long time;
  public MyTimerTask(Runnable task,long delay){
    this.task=task;
    //把delay转换成要执行的任务的“绝对时间戳” 记录下来
    this.time=System.currentTimeMillis()+delay;
  }
  public long getTime(){
    return time;
  }
  public Runnable getTask(){
    return task;
  }
  @Override
  public int compareTo(MyTimerTask o) {
    //this - o  小的优先 就是小堆
    //o-this  大的优先 就是大堆
    return (int)(this.time-o.time);
  }
  
}
class MyTimer{
    private PriorityQueue<MyTimerTask> queue=new PriorityQueue<>();
    private Object locker=new Object();
    public MyTimer(){
        //创建一个线程，任务是否到时间
        Thread t =new Thread(()->{
            //循环的从队列中取元素，然后来判定这个任务是否到达
            //如果到达，就执行任务
            //如果没有到达，就阻塞等待
         synchronized (locker){
            while(true){
                try {
                     if(queue.isEmpty()){
                    locker.wait();
          
                }
                //取出队头元素
                MyTimerTask task = queue.peek();
                //判断队头元素是否到达时间
                if(task.getTime()>System.currentTimeMillis()){
                    locker.wait(task.getTime()-System.currentTimeMillis());
                }
                task=queue.poll();
                task.getTask().run();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
         }

        });
        t.start();

    }
    public void  schedule(Runnable runnable ,long delay){
        synchronized (locker){
            queue.offer(new MyTimerTask(runnable,delay));
            locker.notify();
        }
    }
}
public class Demo36 {
    public static void main(String[] args) {
        MyTimer timer = new MyTimer();
        timer.schedule(()->{
            System.out.println("定时任务3000");
        },3000);
    
     timer.schedule(()->{
        System.out.println("定时任务2000");
    },2000);
         timer.schedule(()->{
        System.out.println("定时任务1000");
    },1000);
    }

}
